
#include <BEvent>

#include "PixmapArea.h"
#include "Operation.h"

Operation::Operation(const BString& name) : BObject(name)
{
	_pixmapArea = 0;
}
Operation::~Operation()
{

}

bool Operation::setPixmapArea(PixmapArea* pixmapArea)
{
	if (_pixmapArea != pixmapArea)
	{
		if (_pixmapArea)
		{
			this->detached(_pixmapArea);
		}
		_pixmapArea = pixmapArea;
		if (_pixmapArea)
		{
			this->attached(_pixmapArea);
		}
		for (int i = 0; i < _children.size(); i++)
		{
			_children[i]->setPixmapArea(_pixmapArea);
		}
		return true;
	}
	return false;
}
PixmapArea* Operation::pixmapArea() const
{
	return _pixmapArea;
}
BPixmap* Operation::pixmap()
{
	if (_pixmapArea)
		return _pixmapArea->pixmap();
	return 0;
}

void Operation::setParent(Operation* parent)
{
	if (_parent != parent && parent != this)
	{
		BHolder<Operation> holder;
		if (_parent)
		{
			holder = this;
			_parent->removeChild(this);
		}
		if (parent)
		{
			parent->addChild(this);
			holder = 0;
		}
	}
}
const Operation* Operation::parent() const
{
	return _parent;
}
Operation* Operation::parent()
{
	return _parent;
}

void Operation::addChild(Operation* child)
{
	if (child && child != this && !_children.contain(child))
	{
		_children.append(child);
		child->_parent = this;
		if (_pixmapArea)
		{
			child->setPixmapArea(_pixmapArea);
			_pixmapArea->fresh();
		}
	}
}
void Operation::removeChild(Operation* child)
{
	if (child && child != this && _children.contain(child))
	{
		child->_parent = 0;
		child->setPixmapArea(0);
		_children.remove(child);
		if (_pixmapArea)
		{
			_pixmapArea->fresh();
		}
	}
}
void Operation::clearChildren()
{
	if (_children.size())
	{
		while (_children.size())
		{
			Operation* child = _children.last();
			child->_parent = 0;
			child->setPixmapArea(0);
			_children.remove(child);
		}
		if (_pixmapArea)
		{
			_pixmapArea->fresh();
		}
	}
}

bool Operation::contains(Operation* child)
{
	return _children.contain(child);
}
bool Operation::contains(const BString& name) const
{
	for (int i = 0; i < _children.size(); i++)
	{
		if (_children[i]->name() == name)
			return true;
	}
	return false;
}

int Operation::childCount() const
{
	return _children.size();
}
Operation* Operation::child(int index) const
{
	return _children(index);
}
Operation* Operation::child(const BString& name) const
{
	for (int i = 0; i < _children.size(); i++)
	{
		if (_children[i]->name() == name)
			return _children[i];
	}
	return 0;
}

bool Operation::detach()
{
	if (_parent)
	{
		_parent->removeChild(this);
		return true;
	}
	if (_pixmapArea)
	{
		_pixmapArea->setOperation(0);
		return true;
	}
	return false;
}
bool Operation::fresh() const
{
	if (_pixmapArea)
	{
		_pixmapArea->fresh();
		return true;
	}
	return false;
}

void Operation::attached(BWidget* widget)
{
	emit(Signal_Attached);
}
void Operation::detached(BWidget* widget)
{
	emit(Signal_Detached);
}

bool Operation::event(const BEvent& event)
{
	if (!_pixmapArea)
		return false;

	for (int i = 0; i < _children.size(); i++)
	{
		Operation* child = _children[i];
		if (!child->enabled())
			continue;
		if (child->event(event))
			return true;
	}

	bool over = false;
	switch (event.type())
	{
	case Event_Update:
		this->update(event.time());
		break;
	case Event_Fresh:
		this->freshEvent(event);
		break;
	case Event_Focus:
		over = this->focusEvent(event);
		break;
	case Event_Move:
		over = this->moveEvent(event);
		break;
	case Event_Resize:
		over = this->resizeEvent(event);
		break;
	case Event_KeyDown:
		over = this->keyDownEvent((const BKeyEvent&)event);
		break;
	case Event_KeyUp:
		over = this->keyUpEvent((const BKeyEvent&)event);
		break;
	case Event_MouseEnter:
		over = this->mouseEnterEvent((const BMouseEvent&)event);
		break;
	case Event_MouseLeave:
		over = this->mouseLeaveEvent((const BMouseEvent&)event);
		break;
	case Event_MouseMove:
		over = this->mouseMoveEvent((const BMouseEvent&)event);
		break;
	case Event_MousePress:
		over = this->mousePressEvent((const BMouseEvent&)event);
		break;
	case Event_MouseRelease:
		over = this->mouseReleaseEvent((const BMouseEvent&)event);
		break;
	case Event_MouseClick:
		over = this->mouseClickEvent((const BMouseEvent&)event);
		break;
	case Event_DoubleClick:
		over = this->mouseDoubleClickEvent((const BMouseEvent&)event);
		break;
	case Event_MouseWheel:
		over = this->mouseWheelEvent((const BMouseEvent&)event);
		break;
	case Event_DragEnter:
		over = this->dragEnterEvent((const BDragEvent&)event);
		break;
	case Event_DragLeave:
		over = this->dragLeaveEvent((const BDragEvent&)event);
		break;
	case Event_DragMove:
		over = this->dragMoveEvent((const BDragEvent&)event);
		break;
	case Event_DragDrop:
		over = this->dragDropEvent((const BDragEvent&)event);
		break;
	default:
		break;
	}

	return over;
}
void Operation::paint(BPainter& painter)
{

}
void Operation::update(double time)
{

}

void Operation::freshEvent(const BEvent& event)
{

}
bool Operation::moveEvent(const BEvent& event)
{
	return false;
}
bool Operation::resizeEvent(const BEvent& event)
{
	return false;
}

bool Operation::focusEvent(const BEvent& event)
{
	return false;
}
bool Operation::keyDownEvent(const BKeyEvent& keyEvent)
{
	return false;
}
bool Operation::keyUpEvent(const BKeyEvent& keyEvent)
{
	return false;
}

bool Operation::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool Operation::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	return false;
}

bool Operation::mousePressEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool Operation::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool Operation::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool Operation::mouseWheelEvent(const BMouseEvent& mouseEvent)
{
	return false;
}

bool Operation::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool Operation::mouseDoubleClickEvent(const BMouseEvent& mouseEvent)
{
	return false;
}

bool Operation::dragEnterEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool Operation::dragLeaveEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool Operation::dragMoveEvent(const BDragEvent& dragEvent)
{
	return false;
}
bool Operation::dragDropEvent(const BDragEvent& dragEvent)
{
	return false;
}
